package com.chinaunicom.emergency.util;

import lombok.extern.log4j.Log4j2;

import java.io.File;
import java.io.InputStream;
import java.util.List;

@Log4j2
public class ConvertMP4 {
    public static void main(String[] args) {
        convert("/Users/Work/jiu.mp4", "/Users/Work/jiuyouhua.mp4");
    }

    public static boolean convert(String inputFile, String outputFile) {
        if (!checkfile(inputFile)) {
            log.error("视频转换出错："+inputFile + " is not file");
            return false;
        }
        if (process(inputFile, outputFile)) {
            return true;
        }
        return false;
    }

    // 检查文件是否存在
    private static boolean checkfile(String path) {
        File file = new File(path);
        if (!file.isFile()) {
            return false;
        }
        return true;
    }

    private static boolean process(String inputFile, String outputFile) {
        int type = checkContentType(inputFile);
        boolean status = false;
        if (type == 0) {
            status = processMP4(inputFile, outputFile);
        }
        return status;
    }

    /**
     * 检查视频类型
     *
     * @param inputFile
     * @return ffmpeg 能解析返回0，不能解析返回1
     */
    public static int checkContentType(String inputFile) {
        String type = inputFile.substring(inputFile.lastIndexOf(".") + 1,
                inputFile.length()).toLowerCase();
        log.info(inputFile + "视频转换开始：格式为："+type);

        // ffmpeg能解析的格式：（asx，asf，mpg，wmv，3gp，mp4，mov，avi，flv等）
        if (type.equals("avi")) {
            return 0;
        } else if (type.equals("mpg")) {
            return 0;
        } else if (type.equals("wmv")) {
            return 0;
        } else if (type.equals("3gp")) {
            return 0;
        } else if (type.equals("mov")) {
            return 0;
        } else if (type.equals("mp4")) {
            return 0;
        } else if (type.equals("asf")) {
            return 0;
        } else if (type.equals("asx")) {
            return 0;
        } else if (type.equals("flv")) {
            return 0;
        }
        // 对ffmpeg无法解析的文件格式(wmv9，rm，rmvb等),
        // 可以先用别的工具（mencoder）转换为avi(ffmpeg能解析的)格式.
        else if (type.equals("wmv9")) {
            return 1;
        } else if (type.equals("rm")) {
            return 1;
        } else if (type.equals("rmvb")) {
            return 1;
        }
        return 1;
    }

    /**
     * ffmepg: 能解析的格式：（asx，asf，mpg，wmv，3gp，mp4，mov，avi，flv等）
     *
     * @param inputFile
     * @param outputFile
     * @return
     */
    private static boolean processMP4(String inputFile, String outputFile) {
        List<String> commend = new java.util.ArrayList<String>();
        // 低精度
        commend.add("ffmpeg");
        commend.add("-i");
        commend.add(inputFile);
        commend.add("-movflags");
        commend.add("faststart");
        commend.add("-b:v");
        commend.add("256k");
//        commend.add("-s");
//        commend.add("720x480");
        commend.add("-c:v");
        commend.add("libx264");
        commend.add("-crf");
        commend.add("18");
        commend.add("-c:a");
        commend.add("copy");
        commend.add("-y");
        commend.add(outputFile);
        StringBuffer test = new StringBuffer();
        for (int i = 0; i < commend.size(); i++)
            test.append(commend.get(i) + " ");
        log.info("开始视频转换，命令为："+test);
        ProcessBuilder builder = new ProcessBuilder();
        builder.command(commend);
        builder.redirectErrorStream(true);
        try {
            Process process = builder.start();
            StringBuffer sb = new StringBuffer();
            try (InputStream in = process.getInputStream()) {
                byte[] bytes = new byte[2048];
                while (in.read(bytes) != -1) {
                    sb.append(new String(bytes,"UTF-8"));
                }
            } catch (Exception e) {
                log.error("视频转换信息获取出错",e);
            }
            log.info("视频转换信息："+sb.toString());
        } catch (Exception e) {
            log.error("视频转换执行出错",e);
            return false;
        }
        return true;
    }

}
